/*
 * $Id: IPLegacyTask.java,v 1.11 2010/06/04 15:36:22 navdeep_mahajan Exp $
 * 
 * Copyright (C) 2006 General Electric Company. All Rights Reserved.
 * 
 * This software is the confidential and proprietary information of the General
 * Electric Company (GE). You shall not disclose this software and shall use it
 * only in accordance with the terms of the license agreement you entered into
 * with GE.
 * 
 * GE MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
 * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
 * NON-INFRINGEMENT. GE SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
 * AS A RESULT OF USING, MODIFYING, OR DISTRIBUTING THIS SOFTWARE OR ITS
 * DERIVATIVES.
 */
package com.ge.healthcare.autosc.processor.dispatcher.tasks;

import java.io.File;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;

import com.ge.healthcare.autosc.common.ASCLogger;
import com.ge.healthcare.autosc.common.ASCUtil;
import com.ge.healthcare.autosc.common.commands.FTPCommand;
import com.ge.healthcare.autosc.common.database.dao.IFileTransferDetailsDAO;
import com.ge.healthcare.autosc.common.database.dao.IRequestPropertiesDAO;
import com.ge.healthcare.autosc.common.database.pojo.ActFileTransferDetails;
import com.ge.healthcare.autosc.common.exceptions.FTPCommandException;
import com.ge.healthcare.autosc.common.util.CheckSumUtil;
import com.ge.healthcare.autosc.processor.exception.ClientDrvCommandException;
import com.ge.healthcare.autosc.processor.exception.IPLegacyException;
import com.ge.healthcare.autosc.processor.exception.IPSweepException;
import com.ge.healthcare.autosc.processor.iip.comm.ClientDrvCommand;
import com.ge.healthcare.autosc.processor.iip.comm.ClientDrvHeartBeat;
import com.ge.healthcare.autosc.processor.iip.comm.IIPResponseParser;
import com.ge.healthcare.autosc.processor.iip.comm.vo.FileInfo;

/**
 * @author 212042764
 * 
 */
public abstract class IPLegacyTask extends BasicTask implements ILegacyTask {
	protected ClientDrvCommand clientDrvCmd = null;
	protected FTPCommand ftp = null;
	protected static IFileTransferDetailsDAO fileTransferDAO = null;
	protected static IRequestPropertiesDAO requestPropertiesDAO = null;

	/**
	 * This is default method to set is Internal as false
	 * 
	 * @param localFile
	 * @param remoteFile
	 * @param prefix
	 * @param requestId
	 * @throws FTPCommandException
	 */
	protected void putBinaryFile(String localFile, String remoteFile,
			String prefix, Long requestId) throws FTPCommandException {
		this.putBinaryFile(localFile, remoteFile, prefix, requestId, false);
	}

	/**
	 * Does the following: 1. Transfers the file to remote device 2. Start
	 * heartbeat so that clientdrv doesn't drops connection 3. Makes an entry in
	 * Act File Transfer details table
	 * 
	 * @param localFile
	 * @param remoteFile
	 * @param prefix
	 * @param requestId
	 * @throws FTPCommandException
	 */
	protected void putBinaryFile(String localFile, String remoteFile,
			String prefix, Long requestId, boolean isInternal)
			throws FTPCommandException {
		String methodName = "putBinaryFile";
		ClientDrvHeartBeat hb = new ClientDrvHeartBeat(clientDrvCmd, prefix
				+ Thread.currentThread().getName());
		boolean successfulTransfer = false;
		Date startDate = new Date();
		try {
			if (hb.isBeatable()) {
				hb.start();
			}
			ftp.setBinaryTransferMode();
			ftp.putFile(localFile, remoteFile);
			successfulTransfer = true;
			ASCLogger.debug(this.getClass(), methodName, new StringBuffer()
					.append("Successfully transferred:").append(localFile)
					.append(" to:").append(remoteFile), true);
		} finally {
			hb.done();
			this.addFileTransferDetails(new File(localFile),
					IFileTransferDetailsDAO.DOWNLOAD_TO_DEVICE, startDate,
					requestId,
					(successfulTransfer ? IFileTransferDetailsDAO.COMPLETED
							: IFileTransferDetailsDAO.FAILED), isInternal);
		}
	}

	/**
	 * Sets internal communication file as false
	 * 
	 * @param localFile
	 * @param remoteFile
	 * @param size
	 * @param prefix
	 * @param requestId
	 */
	protected void getBinaryFile(File localFile, String remoteFile, int size,
			String prefix, Long requestId) {
		this.getBinaryFile(localFile, remoteFile, size, prefix, requestId,
				false);
	}

	/**
	 * Does the following: 1. Transfers the file from remote device 2. Start
	 * heartbeat so that clientdrv doesn't drops connection 3. Makes an entry in
	 * Act File Transfer details table
	 * 
	 * @param localFile
	 * @param remoteFile
	 * @param size
	 * @param prefix
	 * @param requestId
	 */
	protected void getBinaryFile(File localFile, String remoteFile, int size,
			String prefix, Long requestId, boolean isInternal) {
		String methodName = "getBinaryFile";
		ClientDrvHeartBeat hb = new ClientDrvHeartBeat(clientDrvCmd, prefix
				+ Thread.currentThread().getName());
		boolean successfulTransfer = false;
		Date startDate = new Date();
		try {
			if (hb.isBeatable()) {
				hb.start();
			}
			ftp.setBinaryTransferMode();
			ftp.getFile(remoteFile, localFile.getAbsolutePath());
			successfulTransfer = true;
			ASCLogger.debug(this.getClass(), methodName, new StringBuffer()
					.append("Successfully retrieved:").append(remoteFile)
					.append(" as:").append(localFile.getAbsolutePath()), true);
		} catch (FTPCommandException ftpCommandException) {
			throw new IPSweepException(new StringBuffer().append(
					"Failed to retrieve remote file:").append(remoteFile)
					.append(" to:").append(localFile).toString(),
					ftpCommandException, PRC_IPT_F_RBF_001);
		} finally {
			hb.done();
			this.addFileTransferDetails(localFile,
					IFileTransferDetailsDAO.UPLOAD_FROM_DEVICE, startDate,
					requestId,
					(successfulTransfer ? IFileTransferDetailsDAO.COMPLETED
							: IFileTransferDetailsDAO.FAILED), isInternal);
		}
		if (size != 0 && localFile.length() != size) {
			throw new IPSweepException(new StringBuffer().append(
					"Size mismatch found, localfile:").append(
					localFile.getAbsolutePath()).append(" has size:").append(
					localFile.length()).append(" while expected size was:")
					.append(size).toString(), PRC_IPT_F_RTS_001);
		}
	}

	/**
	 * Execute chmod command after transferring files
	 * 
	 * @param umod
	 * @param fileName
	 */
	protected void executeChmodCommand(String umod, String fileName) {
		String response = null;
		try {
			response = clientDrvCmd.executeChmodCommand(umod, fileName);
			if (ASCUtil.isNullOrEmpty(response)) {
				throw new IPSweepException(
						"Failed to chmod, got null response, using clientdrv command ",
						PRC_IPT_F_CDR_004);
			}
			FileInfo chmodResponse = IIPResponseParser
					.parseFileInformation(response.trim());
			if (!chmodResponse.isValid() || chmodResponse.getExitCode() != 0) {
				throw new IPSweepException(new StringBuffer().append(
						"Got invalid response to chmod command ").append(
						" Response:").append(response).toString(),
						PRC_IPT_F_CDR_004);
			}
		} catch (ClientDrvCommandException rexecCmdException) {
			throw new IPSweepException(
					"Failed to chmod using clientdrv command ",
					rexecCmdException, PRC_IPT_F_CDR_004);
		}
	}

	/**
	 * Adds file transfer details to database
	 * 
	 * @param file
	 * @param direction
	 * @param startDate
	 * @param requestId
	 * @param status
	 */
	protected void addFileTransferDetails(File file, String direction,
			Date startDate, Long requestId, String status, boolean isInternal) {
		ActFileTransferDetails fileTransferDetails = new ActFileTransferDetails();
		try {
			if ( file.exists() ){
				fileTransferDetails.setCheckSum(CheckSumUtil.getMD5Checksum(file
						.getAbsolutePath()));
			}
		} catch (NoSuchAlgorithmException nosuchAlgo) {
			throw new IPLegacyException("Failed to get checksum for file:"
					+ file.getAbsolutePath(), nosuchAlgo, PRC_IPT_F_CKS_001);
		} catch (IOException ioException) {
			throw new IPLegacyException("Failed to get checksum for file:"
					+ file.getAbsolutePath(), ioException, PRC_IPT_F_CKS_001);
		}
		fileTransferDetails.setDirection(direction);
		fileTransferDetails.setContentSize(file.length());
		fileTransferDetails.setEndTime(new Date());
		fileTransferDetails.setFileDir(file.getParentFile().getAbsolutePath());
		fileTransferDetails.setFileName(file.getName());
		fileTransferDetails.setRequestId(requestId);
		fileTransferDetails.setStartTime(startDate);
		fileTransferDetails.setStatus(status);
		fileTransferDetails.setInternalCommFile(isInternal);
		fileTransferDAO.save(fileTransferDetails);
	}

	/**
	 * @param fileTransferDAO
	 *            the fileTransferDAO to set
	 */
	public void setFileTransferDAO(IFileTransferDetailsDAO fileTransferDAO) {
		IPLegacyTask.fileTransferDAO = fileTransferDAO;
	}
	
	/**
	 * 
	 * @param requestPropertiesDAO
	 */
	public void setActRequestPropertiesDAO(IRequestPropertiesDAO requestPropertiesDAO) {
		IPLegacyTask.requestPropertiesDAO = requestPropertiesDAO;
	}

}
